package org.elip.teststatistics.client.ui;

import java.util.Date;

import org.elip.teststatistics.client.LogsServiceAsync;
import org.elip.teststatistics.client.ProductServiceAsync;
import org.elip.teststatistics.client.SuitesServiceAsync;
import org.elip.teststatistics.client.TestsServiceAsync;
import org.elip.teststatistics.shared.Log;
import org.elip.teststatistics.shared.Logs;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.VerticalAlignment;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.widget.HorizontalPanel;
import com.extjs.gxt.ui.client.widget.Label;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
import com.extjs.gxt.ui.client.widget.form.DateField;
import com.extjs.gxt.ui.client.widget.form.SimpleComboBox;
import com.extjs.gxt.ui.client.widget.form.SimpleComboValue;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class TestInformationPanel extends HorizontalPanel {
	
	private LogsServiceAsync _logsService;
	private ProductServiceAsync _productService;
	private SuitesServiceAsync _suitesService;
	private TestsServiceAsync _testsService;
	
	private MessageBox _infoTestsRetrieval;
	private MessageBox _infoLogsRetrieval;
	private MessageBox _infoSuitesRetrieval;
	
	private TestLogsPanel _testLogsPanel;
	private TestStatisticsPanel _testStatisticsPanel;
	
	private SimpleComboBox<String> _productComboBox;
	
	private SimpleComboBox<String> _testSuitesComboBox;
	private SimpleComboBox<String> _testNameComboBox;
	
	private DateField _fromDate;
	private DateField _toDate;
	
	private Label _productLabel;
	private Label _testSuiteLabel;
	private Label _testNameLabel;
	
	private Button _goButton;
	
	public TestInformationPanel(TestLogsPanel testLogsPanel, 
			TestStatisticsPanel testStatisticsPanel, LogsServiceAsync logsService, ProductServiceAsync productService,
			SuitesServiceAsync suitesService, TestsServiceAsync testsService) {
		
		this._testLogsPanel = testLogsPanel;
		this._testStatisticsPanel = testStatisticsPanel;
		this._logsService = logsService;
		this._productService = productService;
		this._suitesService = suitesService;
		this._testsService = testsService;
		
		setHorizontalAlign(HorizontalAlignment.CENTER);
		setWidth("100%");
		setHeight(44);
		setTableWidth("100%");
		
		this._productLabel = new Label("Product : ");
		this._testSuiteLabel = new Label("Suite : ");
		this._testNameLabel = new Label("Test Name :");
		this._testSuitesComboBox = new SimpleComboBox<String>();
		this._testNameComboBox = new SimpleComboBox<String>();
		this._productComboBox = new SimpleComboBox<String>();
		
		this._fromDate = new DateField();
		this._toDate = new DateField();
	}
	
	@Override
	protected void onRender(Element parent, int pos) {
		super.onRender(parent, pos);
		
		HorizontalPanel testInformationPanel = new HorizontalPanel();
		testInformationPanel.setSpacing(10);
		testInformationPanel.addStyleName("background-color-container");
		testInformationPanel.setVerticalAlign(VerticalAlignment.MIDDLE);
		
		_productService.generateProducts(new AsyncCallback<String[]>() {
			
			@Override
			public void onSuccess(String[] result) {
				for (String s : result) {
					_productComboBox.add(s);
				}
				_productComboBox.setTriggerAction(TriggerAction.ALL);
				_productComboBox.setForceSelection(true);
				_productComboBox.setEditable(false);
			}
			
			@Override
			public void onFailure(Throwable caught) {
				MessageBox.alert("Sorry", "Couldnt parse products from test-suites.xml config file. check it is properly configured", null);
				caught.printStackTrace();
			}
		});
		_productComboBox.addSelectionChangedListener(new SelectionChangedListener<SimpleComboValue<String>>() {

			@Override
			public void selectionChanged(SelectionChangedEvent<SimpleComboValue<String>> se) {
				@SuppressWarnings("unchecked")
				SimpleComboBox<String> combo = (SimpleComboBox<String>) se.getSource();
				String selection = combo.getValue().getValue();
				_infoSuitesRetrieval = MessageBox.wait("Progress", "Retrieving Suites", "Please wait");
				_testSuitesComboBox.clear();
				_testSuitesComboBox.removeAll();
				_suitesService.generateSuites(selection, new AsyncCallback<String[]>() {
					
					@Override
					public void onSuccess(String[] result) {
						for (String s : result) {
							_testSuitesComboBox.add(s);
						}
						_testSuitesComboBox.setTriggerAction(TriggerAction.ALL);
						_testSuitesComboBox.setForceSelection(true);
						_testSuitesComboBox.setEditable(false);
						_infoSuitesRetrieval.close();
					}
					
					@Override
					public void onFailure(Throwable caught) {
						_infoSuitesRetrieval.close();
						MessageBox.alert("Sorry", "Couldnt parse suites from test-suites.xml config file. check it is properly configured", null);
					}
				});
			}
		});
		
		_testSuitesComboBox.addSelectionChangedListener(new SelectionChangedListener<SimpleComboValue<String>>() {

			@Override
			public void selectionChanged(SelectionChangedEvent<SimpleComboValue<String>> se) {
				@SuppressWarnings("unchecked")
				SimpleComboBox<String> combo = (SimpleComboBox<String>) se.getSource();
				String selectionTest = combo.getValue().getValue();
				_infoTestsRetrieval = MessageBox.wait("Progress", "Retrieving tests", "Please wait");
				_testsService.generateTests(_productComboBox.getValue().getValue(), selectionTest, new AsyncCallback<String[]>() {
					
					@Override
					public void onSuccess(String[] result) {
						_testNameComboBox.clear();
						_testNameComboBox.removeAll();
						for (String s : result) {
							_testNameComboBox.add(s);
						}
						_testNameComboBox.setEnabled(true);
						_infoTestsRetrieval.close();
					}
					
					@Override
					public void onFailure(Throwable caught) {
						_infoTestsRetrieval.close();
						MessageBox.alert("Oops...", "Couldnt retrieve tests", null);
					}
				});
			}
		});
		
		_testNameComboBox.setWidth("250px");
		_testNameComboBox.setTypeAhead(true);
				
		SelectionListener<ButtonEvent> clickListenerGo = new SelectionListener<ButtonEvent>() {
			
			@Override
			public void componentSelected(ButtonEvent ce) {
				
				_infoLogsRetrieval = MessageBox.wait("Progress", "Retrieving logs", "Please wait");
				_testLogsPanel.removeAllTabs();
				_testStatisticsPanel.setPassed(0);
				_testStatisticsPanel.setFailed(0);
				_testStatisticsPanel.setSkipped(0);
				addTestLogs();
			}
		};
		
		_goButton = new Button("Go", clickListenerGo);
		
		testInformationPanel.add(_productLabel);
		testInformationPanel.add(_productComboBox);
		testInformationPanel.add(_testSuiteLabel);
		testInformationPanel.add(_testSuitesComboBox);
		testInformationPanel.add(_testNameLabel);
		testInformationPanel.add(_testNameComboBox);
		testInformationPanel.add(new Label("From:"));
		testInformationPanel.add(_fromDate);
		testInformationPanel.add(new Label("To:"));
		testInformationPanel.add(_toDate);
		testInformationPanel.add(_goButton);
		add(testInformationPanel);
	}
	
	private void addTestLogs() {
		
		String group = _testSuitesComboBox.getValue().getValue();
		String testName = _testNameComboBox.getValue().getValue();
		String product = _productComboBox.getValue().getValue();
		Date fromDate = _fromDate.getValue();
		Date toDate = _toDate.getValue();
		
		AsyncCallback<Logs> callback = new AsyncCallback<Logs>() {
			
			@Override
			public void onSuccess(Logs result) {
				int passed = 0; int failed = 0; int skipped = 0;
				boolean last = false;
				Log[] logs = result.getLogs();
				for (int i = 0 ; i < logs.length ; i++) {
					if (logs[i].isPassed()) passed++;
					if (logs[i].isFailed()) {
						failed++;
					}
					if (logs[i].isSkipped()) skipped++;
					if (i == (logs.length - 1)) last = true;
					_testLogsPanel.addTab(logs[i], last);
				}
				if (result.getLogs().length == 0) {
					MessageBox.info("Logs info", "No logs found", null);
				}
				_testStatisticsPanel.setFailed(failed);
				_testStatisticsPanel.setPassed(passed);
				_testStatisticsPanel.setSkipped(skipped);
				_infoLogsRetrieval.close();
			}
			
			@Override
			public void onFailure(Throwable caught) {
				_infoLogsRetrieval.close();
				MessageBox.alert("Oops...", "Couldnt retrieve logs", null);
				
			}
		};
		
		_logsService.generateLogs(testName, group,product,fromDate, toDate,  callback);
		
	}
	
	

}
